//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-present, Egret Technology.
//  All rights reserved.
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Egret nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////

class Main extends egret.DisplayObjectContainer {

    /**
     * 加载进度界面
     * Process interface loading
     */
    private loadingView: LoadingUI;

    private boom: Boomer[] = [];
    private booms = []
    private mapData = new Array();
    private glowFilter:egret.GlowFilter = new egret.GlowFilter( 0x33CCFF, 0.8, 35, 35,
            2, egret.BitmapFilterQuality.HIGH, false, false );


    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
        // this.addEventListener(BoomEvent.TYPE, this.onDeployBoom, this);
        this.addEventListener(egret.Event.ENTER_FRAME, this.onFrame, this);
        setInterval(this.blink.bind(this), 200);
        window.addEventListener("onDeployBoom", this.onDeployBoom.bind(this));
        window.addEventListener("onCommitCode", this.onCommitCode.bind(this));
        window.addEventListener("gameOver", this.gameOver.bind(this));
    }
    
    public gameOver() {
        let t = new egret.TextField();
        this.addChild(t);
        t.text = "游戏结束";
        t.width = 1280;
        t.height = 768;
        t.size = 140;
        t.textAlign = egret.HorizontalAlign.CENTER;
        t.verticalAlign = egret.VerticalAlign.MIDDLE;

    }
    /*
    * 提交代码后触发的事件
    */
    public onCommitCode(e) {
        console.log(e);
        let detail = e.detail;
        let code = detail.code;
        let index = detail.index;

        // code = code;
        let fun = code;
        fun(this.boom[index]);
    }
    /**
     * 部署炸弹的时候的事件回调
     */
    public onDeployBoom(e) {
        let boom = this.createBitmapByName("boom_png");
        boom.x = e.detail.x;
        boom.y = e.detail.y;

        this.addChild(boom);
        let data = [e.detail.x, e.detail.y, egret.getTimer(), boom]
        this.booms.push(data);
    }

    /**
     * 爆炸处理
     */
    private Boom(x, y) {
        let boomArea = new egret.Shape();
        boomArea.graphics.beginFill(0x66ccff, 1);
        boomArea.graphics.drawRect(x - 64, y - 64, 64 * 3, 64 * 3);
        boomArea.graphics.endFill();
        this.addChild(boomArea);

        this.boom = this.boom.filter((val, index) => {
            console.log("test: ");
            console.log(val);
            if(boomArea.hitTestPoint(val.manX(), val.manY(), true)) {
                console.log("hit");
                this.removeChild(val);
                let ev = new CustomEvent("gameOver");
                window.dispatchEvent(ev);
                return false;
            }else {
                return true;
            }
        });

        setTimeout(() => {
            this.removeChild(boomArea); 
            let mapIndex = 0;
            mapIndex = (x/64) + (y/64)*20;
            this.mapData[mapIndex-1] = 0;
            this.mapData[mapIndex] = 0;
            this.mapData[mapIndex+1] = 0;
            this.mapData[mapIndex-19] = 0;
            this.mapData[mapIndex-20] = 0;
            this.mapData[mapIndex-21] = 0;
            this.mapData[mapIndex+19] = 0;
            this.mapData[mapIndex+20] = 0;
            this.mapData[mapIndex+21] = 0;
            this.updateMap();
        }, 500);
    }
    /**
     * 帧事件回调, 处理炸弹的生命周期和人物的死亡
     */
    public onFrame(e: egret.Event) {
        this.booms.forEach((val, index) => {
            let now = egret.getTimer();
            if (now - val[2] >= 2800 && now - val[2] <= 3000) {
                // 爆炸
                this.Boom(val[0], val[1]);
                this.removeBoom(val[0], val[1]);
            }else if(now - val[2] > 3000) {
                this.removeBoom(val[0], val[1]);
            }
        })
    }

    /**
     * 删除一个位置的炸弹
     */
    public removeBoom(x, y) {
        this.booms = this.booms.filter((val) => {
            // console.log(x2, y2);
            if (x === val[0] && val[1] === y){
                // console.log("false");
                this.removeChild(val[3]);
                return false;
            }else {
                // console.log("true");
                return true;
            }
        });
        // console.log("removeBoom: " + x + "-" + y);
        console.log(this.booms);
    }

    private onAddToStage(event: egret.Event) {

        egret.lifecycle.addLifecycleListener((context) => {
            // custom lifecycle plugin

            context.onUpdate = () => {
                //console.log('hello,world')
            }
        })

        egret.lifecycle.onPause = () => {
            egret.ticker.pause();
        }

        egret.lifecycle.onResume = () => {
            egret.ticker.resume();
        }


        //设置加载进度界面
        //Config to load process interface
        this.loadingView = new LoadingUI();
        this.stage.addChild(this.loadingView);

        //初始化Resource资源加载库
        //initiate Resource loading library
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.loadConfig("resource/default.res.json", "resource/");
    }

    /**
     * 配置文件加载完成,开始预加载preload资源组。
     * configuration file loading is completed, start to pre-load the preload resource group
     */
    private onConfigComplete(event: RES.ResourceEvent): void {
        RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
        RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
        RES.loadGroup("preload");
        RES.loadGroup("game")
    }

    /**
     * preload资源组加载完成
     * Preload resource group is loaded
     */
    private onResourceLoadComplete(event: RES.ResourceEvent) {
        if (event.groupName == "preload") {
            this.stage.removeChild(this.loadingView);
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
            RES.removeEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
            this.createGameScene();
        }
    }

    /**
     * 资源组加载出错
     *  The resource group loading failed
     */
    private onItemLoadError(event: RES.ResourceEvent) {
        console.warn("Url:" + event.resItem.url + " has failed to load");
    }

    /**
     * 资源组加载出错
     *  The resource group loading failed
     */
    private onResourceLoadError(event: RES.ResourceEvent) {
        //TODO
        console.warn("Group:" + event.groupName + " has failed to load");
        //忽略加载失败的项目
        //Ignore the loading failed projects
        this.onResourceLoadComplete(event);
    }

    /**
     * preload资源组加载进度
     * Loading process of preload resource group
     */
    private onResourceProgress(event: RES.ResourceEvent) {
        if (event.groupName == "preload") {
            this.loadingView.setProgress(event.itemsLoaded, event.itemsTotal);
        }
    }
    private map = new Array();
    private initMap(){
        for(var i = 0; i < this.mapData.length; i++){
            var tiled = new egret.Bitmap();
            switch(this.mapData[i]){
                case 1:
                    tiled.texture = RES.getRes("wall_jpg");
                    break;
                default:
                    tiled.texture = RES.getRes("bg_jpg");
                    break;
            }
            tiled.width = 64;
            tiled.height = 64;
            tiled.x = (i%20) * 64; //设置x轴
            tiled.y = Math.floor(i/20) * 64; //设置y轴
            this.map.push(tiled);
            this.addChild(this.map[i]); //加入舞台
        }
    }
    private updateMap(){
        for(var i = 0; i < this.mapData.length; i++){
            switch(this.mapData[i]){
                case 1:
                    this.map[i].texture = RES.getRes("wall_jpg");
                    break;
                default:
                    this.map[i].texture = RES.getRes("bg_jpg");
                    break;
            }
        }
    }
    /**
     * 创建游戏场景
     * Create a game scene
     */
    private createGameScene() {
        // var mapData = new Array(); //地图资源
        for(var i=0; i < 240; i++){
            var r = Math.random() * 10;
            if(r > 9){
                this.mapData[i] = 1;
            }else{
               this.mapData[i] = 0;
            }
        }
        this.initMap();

        let boom1 = new Boomer(64, 64, this.mapData);
        let boom2 = new Boomer(128, 128, this.mapData);
        boom1.filters = [this.glowFilter]
        boom2.filters = [this.glowFilter]
        boom1.enemy = boom2;
        boom2.enemy = boom1;

        this.addChild(boom1);
        this.addChild(boom2);
        this.boom.push(boom1);
        this.boom.push(boom2);

        //this.boom[1].putBoom()
    }
    private blink() {
        this.booms.forEach((val) => {
            if(val[3].filters.length === 0) {
                val[3].filters = [this.glowFilter];
            }else {
                val[3].filters = []
            }
        })
    }
    /**
     * 根据name关键字创建一个Bitmap对象。name属性请参考resources/resource.json配置文件的内容。
     * Create a Bitmap object according to name keyword.As for the property of name please refer to the configuration file of resources/resource.json.
     */
    private createBitmapByName(name: string) {
        let result = new egret.Bitmap();
        let texture: egret.Texture = RES.getRes(name);
        result.texture = texture;
        return result;
    }
}


